package org.oos.services;

import java.net.URL;

import org.apache.commons.codec.digest.DigestUtils;
import org.oos.services.util.AtomUtils;
import org.oos.services.util.URLUtils;
import org.w3c.dom.Document;
import org.w3c.dom.Element;

/**
 * Implements the methods needed to get user authentication for a given a application, as stated in:
 * http://groups.google.com/group/api-11870/web/rapid-guide-to-authenticate-a-user-in-11870-from-my-mashup
 */
public class UserAuth
{
	public enum Permission { READ, WRITE }
	public URLUtils urlUtils = new URLUtils();
	AtomUtils atom = new AtomUtils();
	
	/**
	 * First step: get the temporal token. This token is valid only for a 
	 * single interaction with a single user. This token is needed for the next step. 
	 * @return temporal token
	 * @throws OOSException could not get the token
	 */
	public String getTempToken(String appToken, String secret) throws OOSException
	{
		try
		{
			String authSign = DigestUtils.md5Hex(appToken+secret);
			String urlString = "http://11870.com/manage-api/temp-token?appToken="+appToken+"&authSign="+authSign;
			Document doc = urlUtils.retrieve(new URL(urlString));
			Element root = doc.getDocumentElement();
			String tempToken = atom.getValue(root);
			return tempToken;
		}
		catch (Exception e)
		{
			throw new OOSException("could not get tempToken", e);
		}
	}
	
	/**
	 * Second step: redirect the user to the URL this method returns. If the temporal token
	 * is not valid, the method raises an exception. The permission could be one of <code>READ</code> and <code>WRITE</code>
	 * @param tempToken token got in first step (getTempToken method)
	 * @return url where the user should be directed to complete authorization 
	 * @throws OOSException there is no temp token or it is not valid, first step must be completed before calling 
	 */
	public String getAuthURL(String tempToken, Permission permission) throws OOSException
	{
		if (tempToken==null || permission==null)
		{
			throw new OOSException("User authentication url can not be build, invalid parameters. Remember you'd need a temporal token to get to this point");
		}
		try
		{
			return "http://11870.com/manage-api/create-token?tempToken="+tempToken+"&privilege="+permission;
		}
		catch(Exception e)
		{
			throw new OOSException("could not build authentication url", e);
		}
	}

	/**
	 * Third and last step: the user has already completed the authorization in the url 
	 * from step 2. If this method returns a String, this is the valid one, if the previous
	 * steps were not completed, this method returns an exception.
	 * @return user authentication token, valid from now on for this user.
	 * @throws OOSException Authorization could not be completed ot tempToken is not valid
	 */
	public String getAuthToken(String tempToken) throws OOSException
	{
		try
		{
			String urlString = "http://11870.com/manage-api/auth-token?tempToken="+tempToken;
			Document doc = urlUtils.retrieve(new URL(urlString));
			return atom.getValue(doc.getDocumentElement());
		}
		catch (Exception e)
		{
			throw new OOSException("could not get user's authorization token, perhaps user never finished step 2", e); 
		}
	}
	
	/**
	 * Parses the service document for the user slug.
	 * @return user slug
	 * @throws OOSException
	 */
	public String getUserSlug(String email, String authToken) throws OOSException
	{
		try
		{
			String urlString = "http://11870.com/api/v1";
			Document doc = urlUtils.retrieveWSSE(new URL(urlString), email, authToken);
			String slug = atom.getElementHrefValue(doc.getDocumentElement(), "collection");
			String[] tokens  = slug.split("/");
			return tokens[tokens.length-1];
		}
		catch (Exception e)
		{
			throw new OOSException("could not get user slug, perhaps application is not authenticated", e); 
		}
	}

	/**
	 * Parses the service document for the user slug.
	 * @return user slug
	 * @throws OOSException
	 */
	public String[] getServiceDocument(String email, String authToken) throws OOSException
	{
		try
		{
			String urlString = "http://11870.com/api/v1";
			org.jdom.Document doc = urlUtils.retrieveJDomWSSE(new URL(urlString), email, authToken);
			
			String[] serv = new String[4];
			org.jdom.Element service = doc.getRootElement();
			serv[0] = service.getAttribute("xml:base").getValue();
			return serv;
		}
		catch (Exception e)
		{
			throw new OOSException("could not get user slug, perhaps application is not authenticated", e); 
		}
	}
}
